package com.luanye.enjoy.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.luanye.enjoy.dto.ApplyFormDTO;
import com.luanye.enjoy.dto.CityDTO;
import com.luanye.enjoy.entity.Beauty;
import com.luanye.enjoy.entity.User;
import com.luanye.enjoy.entity.Village;
import com.luanye.enjoy.enums.ResultCode;
import com.luanye.enjoy.mapper.VillageMapper;
import com.luanye.enjoy.service.BeautyService;
import com.luanye.enjoy.service.UserService;
import com.luanye.enjoy.service.VillageService;
import com.luanye.enjoy.utils.BeanCopyUtils;
import com.luanye.enjoy.utils.SecurityUtils;
import com.luanye.enjoy.vo.ProcessFormVo;
import com.luanye.enjoy.vo.ProcessVo;
import com.luanye.enjoy.vo.RespBean;
import lombok.AllArgsConstructor;
//import org.flowable.engine.HistoryService;
//import org.flowable.engine.RuntimeService;
//import org.flowable.engine.TaskService;
//import org.flowable.engine.runtime.ProcessInstance;
//import org.flowable.task.api.Task;
//import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.GeoResult;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.domain.geo.GeoReference;
import org.springframework.data.redis.domain.geo.Metrics;
import org.springframework.stereotype.Service;
import java.util.*;
import static com.luanye.enjoy.constants.RedisConst.PROCESS_USER_KEY;
import static com.luanye.enjoy.constants.RedisConst.VILLAGE_GEO_KEY;
import static com.luanye.enjoy.constants.SystemConst.DEPLOY_ID;
import static com.luanye.enjoy.constants.SystemConst.MAX_PAGE_SIZE;

@Service("villageService")
@AllArgsConstructor
public class VillageServiceImpl extends ServiceImpl<VillageMapper, Village> implements VillageService {

    private final UserService userService;

    //private final RuntimeService runtimeService;

    private final StringRedisTemplate stringRedisTemplate;

    //private final HistoryService historyService;
    //
    //private final TaskService taskService;

    private final BeautyService beautyService;

    @Override
    public RespBean apply(ApplyFormDTO dto) {
        ////手机号判空检测
        //Long userId = SecurityUtils.getUserId();
        //User user = userService.getById(userId);
        //if (Objects.isNull(user.getPhone())){
        //    return RespBean.error(ResultCode.PHONE_ERROR);
        //}
        //String key = PROCESS_USER_KEY + userId;
        //String s = stringRedisTemplate.opsForValue().get(key);
        //if (Objects.nonNull(s)){
        //    return RespBean.error(ResultCode.NOT_FLUENT_OPERATE);
        //}
        //// 存入数据库
        //Village village = BeanCopyUtils.copyBean(dto, Village.class);
        //if (dto.getIsDraft() == 0){
        //    village.setIsCheck(0);
        //    save(village);
        //    return RespBean.success();
        //}
        //save(village);
        ////开启流程 加 手机号 phone userid village_id
        //Map<String, Object> map = JSON.parseObject(JSON.toJSONString(village), new TypeReference<Map<String, Object>>() {});
        //map.put("phone", user.getPhone());
        //map.put("userid", userId);
        //map.put("village_id", village.getId());
        //ProcessInstance processInstance = runtimeService.startProcessInstanceById(DEPLOY_ID, map);
        //
        ////缓存用户流程关系
        //String processInstanceId = processInstance.getId();
        //
        //stringRedisTemplate.opsForValue().set(key, processInstanceId);
        //
        ////返回流程id
        //return RespBean.success(processInstanceId);
        return null;
    }

    @Override
    public RespBean getForm() {
        //Long userId = SecurityUtils.getUserId();
        //String key = PROCESS_USER_KEY + userId;
        //
        //String processInstanceId = stringRedisTemplate.opsForValue().get(key);
        //
        //List<Task> list = taskService.createTaskQuery()
        //        .processInstanceId(processInstanceId)
        //        .active().list();
        //ProcessFormVo vo = new ProcessFormVo();
        //
        //if (list.size() == 0)
        //    vo.setFlag(3);
        //else
        //    vo.setFlag(2);
        //
        //List<HistoricTaskInstance> history = historyService.createHistoricTaskInstanceQuery()
        //        .processInstanceId(processInstanceId)
        //        .orderByHistoricTaskInstanceEndTime()
        //        .asc().list();
        //List<ProcessVo> processVos = new ArrayList<>();
        //
        //for (int i = 0; i < history.size(); i++){
        //    HistoricTaskInstance instance = history.get(i);
        //    if (instance.getEndTime() == null) continue;
        //
        //    String name = instance.getName();
        //    String assignee = "";
        //    switch (name){
        //        case "审核用户基本信息":
        //            assignee = "李行";
        //            break;
        //        case "审核乡村信息":
        //            assignee = "史宏博";
        //            break;
        //        case "优质乡村鉴定":
        //            assignee = "张露";
        //            break;
        //        case "终审" :
        //            assignee = "吕国伟";
        //            break;
        //    }
        //
        //    ProcessVo process = new ProcessVo()
        //            .setName(name)
        //            .setEndTime(instance.getEndTime())
        //            .setAssignee(assignee)
        //            ;
        //
        //    processVos.add(process);
        //
        //}
        //
        //vo.setProcessVos(processVos);
        //
        //return RespBean.success(vo);
        return null;
    }

    @Override
    public RespBean listByGeo(Integer current, Double x, Double y) {
        if (x == null || y == null){
            Page<Village> page = query().page(new Page<>(current, MAX_PAGE_SIZE));
            return RespBean.success(page.getRecords());
        }
        // 获取分页参数
        int from = (current - 1) * MAX_PAGE_SIZE;
        int end = current * MAX_PAGE_SIZE;

        String key = VILLAGE_GEO_KEY;

        GeoResults<RedisGeoCommands.GeoLocation<String>> results = stringRedisTemplate.opsForGeo()
                .search(
                        key,
                        GeoReference.fromCoordinate(x, y),
                        new Distance(30, Metrics.KILOMETERS),
                        RedisGeoCommands.GeoSearchCommandArgs.newGeoSearchArgs().includeDistance().limit(end)
                );
        if (results == null){
            return RespBean.success(Collections.emptyList());
        }
        List<GeoResult<RedisGeoCommands.GeoLocation<String>>> list = results.getContent();
        if (list.size() <= from){
            return RespBean.success(Collections.emptyList());
        }
        List<Long> ids = new ArrayList<>(list.size());

        Map<String, Distance> distanceMap = new HashMap<>(list.size());

        list.stream().skip(from)
                .forEach( result -> {
                    //获取店铺id
                    String villageId = result.getContent().getName();
                    ids.add(Long.valueOf(villageId));
                    //获取距离
                    Distance distance = result.getDistance();
                    distanceMap.put(villageId, distance);
                });
        //根据id查Village
        String idStr = StrUtil.join(",", ids);
        List<Village> villages = query().in("id", ids).last("ORDER BY FIELD(id," + idStr + ")").list();
        for (Village village : villages){
            village.setDistance(distanceMap.get(village.getId().toString()).getValue());
        }
        return RespBean.success(villages);
    }

    @Override
    public RespBean getCityList() {
        List<String> cityS = baseMapper.getCityS();
        return RespBean.success(cityS);
    }

    @Override
    public RespBean getVillageListByCity(CityDTO dto) {
        Page<Village> villagePage = query().eq("city", dto.getName()).page(new Page<>(dto.getCurrent(), MAX_PAGE_SIZE));
        return RespBean.success(villagePage.getRecords());
    }

    @Override
    public RespBean getDetail(Long id) {
        Village village = getById(id);
        //获取景点
        LambdaQueryWrapper<Beauty> query = new LambdaQueryWrapper<>();
        query.eq(Beauty::getVillageId, village.getId());
        query.orderByDesc(Beauty::getCreateTime);
        List<Beauty> beauties = beautyService.getBaseMapper().selectList(query);
        village.setBeauties(beauties);
        return RespBean.success(village);
    }
}

